#ifndef EXECUTION_ORDER_SOLUTION_H
#define EXECUTION_ORDER_SOLUTION_H
#include <iostream>
#include <algorithm>
#include <vector>
#include <unordered_map>
#include <fstream>
#include <string>
#include <chrono> // 包含时间库
#include <thread>
#include <functional>
#include <set>
#include <cmath>
#include <mutex>
#include <queue>
#include "dag.h"
#include "../node.h"

class Solution
{
private:
    DAG dag;
    size_t n;
    size_t m;
    std::vector<size_t> op_result_card;      // 算子结果所在卡
    std::vector<long long> last_trans_end_t; // 上次传输结束时间
    std::vector<long long> prio;             // 算子优先级
    
    std::vector<long long> cal_cost;
    std::vector<long long> trans_cost;
    
    size_t st;
    size_t en;
    std::vector<size_t> unordered_q;
    std::set<std::pair<long long, size_t>> q; // 基于优先级排序的算子队列
    std::vector<long long> q_free_t;
    std::vector<std::pair<size_t, size_t>> res; // 卡id,算子id
    std::vector<std::pair<size_t, size_t>> best_res;
    long long cost;
    long long best_cost;
    std::vector<bool> accessed;
    size_t cnt_from_last_optimize;
    bool is_first_round = true;

public:
    Solution(size_t n, size_t m, const std::vector<std::vector<size_t>> &pre_ids, const std::vector<long long> &cal_use_times, const std::vector<long long> &trans_use_times);
    Solution(const Solution&) = delete;
    Solution& operator=(const Solution&) = delete;

    Solution(Solution&&) = default;
    Solution& operator=(Solution&&) = default;  

    // 计算理论最优值，不考虑传输时间
    long long theoretical_best();
    // 随机算子
    size_t get_random_operator();
    // 优先级算子
    size_t get_prio_operator();
    // 获取下一个计算的算子
    size_t get_nex_operator();
    // 随机选择卡
    size_t get_random_card();
    // 获取时间最小的卡
    size_t get_cal_t_min_card(size_t op);
    
    size_t get_user_free_card(size_t op)
    {
        return get_cal_t_min_card(op);
    }
    // 主流程
    void work();
    void show_best_res(const std::vector<size_t> &ids);

    std::pair<long long, std::vector<std::pair<size_t, size_t>>> get_best_res();
    static void merge_best_res(Solution &sol1, Solution &sol2);
    void cp_best_res(Solution &sol)
    {
        best_cost = sol.best_cost;
        best_res = sol.best_res;
    }
    std::vector<std::pair<size_t, size_t>> get_res() const {
        return res;
    }
    long long get_cost() const {
        return cost;
    }

    // 对结果进行优化
    void optimize_res(bool optimize_best_res = true);
    
};


std::vector<std::pair<size_t, size_t>>
ExecuteOrder(const std::vector<Node *> &all_nodes, size_t card_num);

#endif // EXECUTION_ORDER_SOLUTION_H
